package com.urbanski.clipboard.server.session;

import static com.urbanski.clipboard.common.util.CommonConstants.NEWLINE;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.urbanski.clipboard.server.ClientSocket;

public class ServerSession
{
	private String sessionName;
	private String adminPassword;
	private String sessionPassword;
	private Map<String, ClientSocket> clients = new HashMap<>();
	private boolean paused = false;
	private Set<String> pausedClients = new HashSet<>();
	
	public ServerSession(String sessionName, String adminPassword)
	{
		this(sessionName, adminPassword, null);
	}
	
	public ServerSession(String sessionName, String adminPassword, String sessionPassword)
	{
		this.sessionName = sessionName;
		this.adminPassword = adminPassword;
		this.sessionPassword = sessionPassword;
	}

	public String getAdminPassword()
	{
		return adminPassword;
	}

	public void setAdminPassword(String adminPassword)
	{
		this.adminPassword = adminPassword;
	}

	public String getSessionPassword()
	{
		return sessionPassword;
	}

	public void setSessionPassword(String sessionPassword)
	{
		this.sessionPassword = sessionPassword;
	}

	public String getSessionName()
	{
		return sessionName;
	}

	public Map<String, ClientSocket> getClients()
	{
		return clients;
	}
	
	public boolean addClient(ClientSocket client)
	{
		return clients.put(client.getClientName(), client) == null;
	}
	
	public boolean removeClient(ClientSocket client)
	{
		return clients.remove(client.getClientName()) != null;
	}
	
	public boolean clientExists(String clientName)
	{
		return clients.containsKey(clientName);
	}
	
	public boolean isPaused()
	{
		return paused;
	}

	public void setPaused(boolean paused)
	{
		this.paused = paused;
	}
	
	public boolean pauseClient(String clientName)
	{
		if (clientExists(clientName))
		{
			return pausedClients.add(clientName);
		}
		
		return false;
	}
	
	public boolean unpauseClient(String clientName)
	{
		if (clientExists(clientName))
		{
			return pausedClients.remove(clientName);
		}
		
		return false;
	}
	
	public boolean clientPaused(String clientName)
	{
		return pausedClients.contains(clientName);
	}

	public String toString()
	{
		StringBuilder sb = new StringBuilder();
		sb.append("Session name: ").append(sessionName).append(NEWLINE);
		sb.append("Password: ").append(sessionPassword).append(NEWLINE);
		sb.append("Admin password: ").append(adminPassword).append(NEWLINE);
		sb.append("Clients: ");
		if (clients.size() == 0)
		{
			sb.append("<none>");
		}
		else
		{
			for (ClientSocket client : clients.values())
			{
				sb.append(NEWLINE).append('\t').append(client.getClientName());
				if (pausedClients.contains(client.getClientName()))
				{
					sb.append(" (paused)");
				}
			}
		}
		
		return sb.toString();
	}

	public void removeClient(String clientName)
	{
		clients.remove(clientName);
		pausedClients.remove(clientName);
	}
}
